package com.example.blogserver.config;

import com.example.blogserver.a_utils.GetBean;
import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.DigestUtils;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;

@SuppressWarnings({"all"})
public class RedisCache implements Cache {
    //当前放入缓存的mapper的namespace
    private final String id;

    //构造方法
    public RedisCache(String id) {
        this.id = id;
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        return Cache.super.getReadWriteLock();
    }

    @Override
    public String getId() {
        return this.id;
    }

    /**
     * 往Redis缓存中放 RedisTemplate StringRedisTemplate
     */
    @Override
    public void putObject(Object key, Object value) {
        //使用Redis中的hash类型作为缓存存储模型 key hashkey value
        getRedisTemplate().opsForHash().put(id.toString(),getKeyToMd5(key.toString()),value);

        //针对不同业务模块设置不同的过期时间
        //用户信息缓存
        if (id.equals("com.example.demo.mapper.UserMapper")){
            //用户信息设置1小时过期
            getRedisTemplate().expire(id.toString(),1, TimeUnit.HOURS);
        }
        //文章信息缓存
        if (id.equals("com.example.demo.mapper.ArticleMapper")){
            //文章信息设置1天过期
            getRedisTemplate().expire(id.toString(),1,TimeUnit.DAYS);
        }
    }

    @Override
    public Object getObject(Object key) {
        //根据key从redis的hash类型方法中获取数据
        Object res = getRedisTemplate().opsForHash().get(id.toString(),getKeyToMd5(key.toString()));
        return res;
    }

    @Override
    public Object removeObject(Object o) {
        return null;
    }

    @Override
    public void clear() {
        //清空hash
        getRedisTemplate().delete(id.toString());//清空缓存
    }

    @Override
    public int getSize() {
        //获取hash中key value的数量
        return getRedisTemplate().opsForHash().size(id.toString()).intValue();
    }

    /**
     * 封装RedisTemplate
     */
    public RedisTemplate getRedisTemplate(){
        RedisTemplate redisTemplate = (RedisTemplate) GetBean.getBean("redisTemplate");
        //修改序列化方案
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        return redisTemplate;
    }

    /**
     * 使用MD5算法对key进行加密
     */
    private static String getKeyToMd5(String key){
        return DigestUtils.md5DigestAsHex(key.getBytes());
    }
}
